package com.ixuea.courses.mycloudmusicapisp.controller.v1;


import com.ixuea.courses.mycloudmusicapisp.annotation.Authorization;
import com.ixuea.courses.mycloudmusicapisp.annotation.CurrentUser;
import com.ixuea.courses.mycloudmusicapisp.domain.Account;
import com.ixuea.courses.mycloudmusicapisp.domain.User;
import com.ixuea.courses.mycloudmusicapisp.exception.ArgumentException;
import com.ixuea.courses.mycloudmusicapisp.exception.CommonException;
import com.ixuea.courses.mycloudmusicapisp.service.UserService;
import com.ixuea.courses.mycloudmusicapisp.util.BCryptUtil;
import com.ixuea.courses.mycloudmusicapisp.util.Constant;
import com.ixuea.courses.mycloudmusicapisp.util.ResponseUtil;
import com.ixuea.courses.mycloudmusicapisp.util.SHAUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;

/**
 * 用户控制器
 */
@RestController
@Slf4j
@RequestMapping("/v1")
public class UserController {

    /**
     * 用户服务
     */
    @Autowired
    private UserService service;



    /**
     * 创建用户（注册）
     *
     * @param data 用户对象
     * @return 返回
     */
    @PostMapping(path = "users")
    @ResponseBody
    public Object create(@Valid @RequestBody User data, BindingResult bindingResult) {
        //参数校验

        //框架提供的参数校验
        if (bindingResult.hasErrors()) {
            //创建列表保存错误详细错误
            List<String> detail = new ArrayList<>();

            //获取所有错误信息
            List<ObjectError> errors = bindingResult.getAllErrors();

            //把错误提示填加到列表
            for (ObjectError error:errors) {
                detail.add(error.getDefaultMessage());
            }

            //抛出自定义异常并传入详细的错误信息
            throw new CommonException(Constant.ERROR_ARGUMENT, Constant.ERROR_ARGUMENT_MESSAGE, detail);
        }

        //判断用户是否已经存在
        if(service.findByPhone(data.getPhone()) != null ||
                service.findByEmail(data.getEmail()) != null) {
            throw new CommonException(Constant.ERROR_USER_EXIST, Constant.ERROR_USER_EXIST_MESSAGE);
        }

        //加密数据
        data.encryptData();

        //保存用户
        if (!service.create(data)) {
            throw new CommonException(Constant.ERROR_SAVE_DATA, Constant.ERROR_SAVE_DATA_MESSAGE);
        }


        //返回用户对象
        return ResponseUtil.wrap(data.getId());
    }

    /**
     * 用户列表
     *
     * @return 返回
     */
    @RequestMapping("/users")
    public Object users() {
        //查询所有用户
        List<User> datum = service.findAll();

        //返回数据
        return ResponseUtil.wrap(datum);
    }


    /**
     * 用户详情
     *
     * @param id id
     * @return 返回
     */
    @RequestMapping("/users/{id}")
    public Object userDetails(@PathVariable("id") String id) {
        //打印日志
        log.info("userDetails:{}", id);

        //查询数据
        User data = service.find(id);

        //返回数据
        return ResponseUtil.wrap(data);
    }

    /**
     * 绑定第三方账号
     *
     * @param data
     * @param bindingResult
     * @param currentUser
     * @return
     */
    @PostMapping(path = "/users/bind")
    @Authorization
    public Object bindAccount(@Valid @RequestBody Account data, BindingResult bindingResult, @CurrentUser User currentUser) {
        //判断参数
        if (bindingResult.hasErrors()) {
            //参数错误
            throw new ArgumentException();
        }

        //判断更新平台取值是否正确
        String accountField = null;
        if (data.getPlatform() == Constant.PLATFORM_QQ) {
            accountField = "qq_id";
        } else if (data.getPlatform() == Constant.PLATFORM_WEIBO) {
            accountField = "weibo_id";
        } else {
            //参数错误
            throw new ArgumentException();
        }

        //加密信息
        String accountDigest = BCryptUtil.encrypt(data.getAccount());

        //更新用户
        if (!service.updateAccount(currentUser.getId(),
                SHAUtil.sha1(data.getAccount()),
                accountDigest,
                accountField)) {
            //参数错误
            throw new ArgumentException();
        }

        return ResponseUtil.wrap(currentUser.getId());
    }


}
